#include <linux/idr.h>
#include <linux/list.h>
#include <linux/stdlib.h>
#include <linux/errno.h>
#include <linux/bug.h>

#define IDR_CHUNK_SIZE 16

struct idr_node
{
    struct list_head idr_list;
    void *slots[IDR_CHUNK_SIZE];
    unsigned long index_start;
    DECLARE_BITMAP (used, IDR_CHUNK_SIZE);
};

/**
 * idr_alloc_u32() - Allocate an ID.
 * @idr: IDR handle.
 * @ptr: Pointer to be associated with the new ID.
 * @nextid: Pointer to an ID.
 * @max: The maximum ID to allocate (inclusive).
 * @gfp: Memory allocation flags.
 *
 * Allocates an unused ID in the range specified by @nextid and @max.
 * Note that @max is inclusive whereas the @end parameter to idr_alloc()
 * is exclusive.  The new ID is assigned to @nextid before the pointer
 * is inserted into the IDR, so if @nextid points into the object pointed
 * to by @ptr, a concurrent lookup will not find an uninitialised ID.
 *
 * The caller should provide their own locking to ensure that two
 * concurrent modifications to the IDR are not possible.  Read-only
 * accesses to the IDR may be done under the RCU read lock or may
 * exclude simultaneous writers.
 *
 * Return: 0 if an ID was allocated, -ENOMEM if memory allocation failed,
 * or -ENOSPC if no free IDs could be found.  If an error occurred,
 * @nextid is unchanged.
 */
int
idr_alloc_u32(struct idr *idr, void *ptr, u32 *nextid,
              unsigned long max, gfp_t gfp)
{

    return 0;
}

int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp)
{
    u32 id = start;
    int ret;

    if (WARN_ON_ONCE(start < 0))
        return -EINVAL;

    return 0;
}

void *idr_remove(struct idr *idr, unsigned long id)
{
}
